package auth

import (
	"errors"
	"time"

	"github.com/golang-jwt/jwt/v4"
)

type AuthService struct {
	secret        string
	tokenDuration time.Duration
}

type Claims struct {
	UserID   string `json:"user_id"`
	Username string `json:"username"`
	jwt.RegisteredClaims
}

func NewAuthService(secret string, tokenDuration time.Duration) *AuthService {
	return &AuthService{
		secret:        secret,
		tokenDuration: tokenDuration,
	}
}

// GenerateToken 生成JWT Token
func (a *AuthService) GenerateToken(userID, username string) (string, int64, error) {
	expiresAt := time.Now().Add(a.tokenDuration)

	claims := &Claims{
		UserID:   userID,
		Username: username,
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(expiresAt),
			IssuedAt:  jwt.NewNumericDate(time.Now()),
			Issuer:    "platform-gateway",
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err := token.SignedString([]byte(a.secret))
	if err != nil {
		return "", 0, err
	}

	return tokenString, expiresAt.Unix(), nil
}

// VerifyToken 验证JWT Token
func (a *AuthService) VerifyToken(tokenString string) (string, string, error) {
	token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(a.secret), nil
	})

	if err != nil {
		return "", "", err
	}

	if claims, ok := token.Claims.(*Claims); ok && token.Valid {
		return claims.UserID, claims.Username, nil
	}

	return "", "", errors.New("invalid token")
}
